当在 Web 浏览器中请求一个网页,而网页中又使用 XMLHttpRequest 发送请求时,只能请求位于同一超域中任意服务器上的资源,这就是 " 超域匹配 " 规则,它可以避免网页中的 XMLHttpRequest 从其它人的服务器上下载信息。此限制是出于安全性的考虑。
例如,下面的代码位于网页 http://localhost/myPage.html
内,而请求的 XMLHttpRequest 网址却是 http://myhost/employees.xml
,不在同一个超域内:
var oXMLHttpRequest = new XMLHttpRequest();
try {
oXMLHttpRequest.open('GET ', `http://lmssee.com/employees.xml`, true);
oXMLHttpRequest.send(null);
} catch (err) {
alert(err.message ? err.message : err.toString());
}
在某些特殊的情况下,用户恰恰需要实现跨域请求,这可以通过在服务器端创建一个代理来实现,而代理一般使用服务端动态脚本来实现,如下所示:
proxy.asp <%@ LANGUAGE=VBScript%> <% Response.Buffer=True Dim oConn, strURL // 指定 URL
strURL = "<a href=\"http://myhost/employees.xml"\"
rel=\"nofollow\">http://myhost/employees.xml"</a>";
Set oConn = Server.CreateObject("Microsoft.XMLHTTP") // 连接到 URL
oConn.Open "GET", strURL, False // 发送请求 oConn.Send
resultData = oConn.responseText // 设置内容类型
Response.ContentType = oConn.getResponseHeader("Content-Type")
Response.Write (resultData)
Set oConn = Nothing Response.End %>
将 proxy.asp 放置到本域服务器,然后直接请求 proxy.asp ,让它作为代理调用另一个域内的资源,并将资源返回即可:
使用 XDomainRequest 的方法和属性来向服务器发送请求和从服务器获取响应,类似于 XMLHttpRequest 。但是, XDomainRequest 可以实现跨域访问,该类是 IE 独有的。
XDomainRequest 的方法和属性与 XMLHttpRequest 基本相同,仅仅新增了 3 个事件属性,而不需要再检测响应状态。现在,一个完整的 AJAX 程序就如下面的代码:
function onError() {
window.status = ' 出错! ';
}
function onLoad() {
//处理返回的结果
console.log(' 数据 == < xmp >' + oXDomainRequest.responseText + ' < /xmp> ');
}
function onProgress() {
window.status = ' 正在加载, 请稍等! ';
}
function onTimeout() {
window.status = ' 超时! ';
}
var oXDomainRequest = new XDomainRequest();
oXDomainRequest.onerror = onError;
oXDomainRequest.onload = onLoad;
oXDomainRequest.onprogress = onProgress;
oXDomainRequest.ontimeout = onTimeout;
try {
oXDomainRequest.open('GET ', 'http://127.0.0.1/employees.xml'); // 设置请求超时时间,这里设一个较低值用于测试
oXDomainRequest.timeout = 1;
oXDomainRequest.send(null);
} catch (err) {
alert(err.message ? err.message : err.toString());
}
XDomainRequest 实例可以通过 window 对象的 XDomainRequest 属性获得,也可以使用 new 关键字实例化一个 XDomainRequest 对象:
var oXDomainRequest = window.XDomainRequest;
var oXDomainRequest = new XDomainRequest();
XDomainRequest 使用 W3C 跨域访问控制的规范来实现跨域访问的权限。它将会发送名为 Origin 的 HTTP 报头,而服务器必须返回 Access-Control-Allow-Origin 的 HTTP 报头,目前仅能设置值为 "* " ,这样, IE8 才能允许解析返回的值,同时这也表明服务器允许跨域访问。
不过根据 W3C 跨域访问控制的规范,也可以指定允许访问的域,相信未来 IE8 会增加这一功能。用户可以通过网址 http://www.w3.org/TR/access-control/
了解跨域访问控制规范。有多种方式可以定义 Access-Control-Allow-Origin 报头,下面进行简单介绍。
如果要将整个站点设置为可以跨域访问,那么为该站点添加一个自定义报头。
一些动态脚本语言(如 ASP 、 ASP.NET 、 JSP 、 PHP 等)都可以动态创建 HTTP 响应报头,下面的分别是它们创建默认内容类型的代码。
ASP 代码。
<%Response.AddHeader "Access-Control-Allow-Origin ", "* "%>
JSP 代码。
<%response.addHeader( "Access-Control-Allow-Origin ", "*");%>
PHP 代码。
<?php header( "Access-Control-Allow-Origin: *");?>
ASP.NET 代码( C# 和 VB 适用, C# 注意以分号结尾)。
<%response.AppendHeader( "Access-Control-Allow-Origin ","\* ")%>
Firefox 3.1 及更新版本也可以使用 XMLHttpRequest 来发送 Origin 报头,只要服务器返回 Access-Control-Allow-Origin 报头,那么也可以实现跨域访问。
古老的跨域解决方案。